<!DOCTYPE html>
<html>
<head>
	<title>chencaicc-小年祝福</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1"/>
	<style type="text/css">
		body {
            width:100%;
            overflow:hidden;
    margin: 0;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: black;
}

.neon {
    width:1920px;
    text-align: center;
    position: relative;
    overflow: hidden;
    filter: brightness(200%);
    z-index:88;
}

.text {
    display:block;

    background-color: black;
    color: white;
    font-size: 180px;
    font-weight: bold;
    font-family: sans-serif;
    text-transform: uppercase;
    position: relative;
    user-select: none;
}


@media (max-width: 767px) {
    .text{
        font-size: 60px
    }

}

.text::before {
    content: attr(data-text);
    position: absolute;
    color: white;
    filter: blur(0.02em);
    mix-blend-mode: difference;
}

.gradient {
    position: absolute;
    background: linear-gradient(45deg, red, gold, lightgreen, gold, red);
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    mix-blend-mode: multiply;
}

.spotlight {
    position: absolute;
    top: -100%;
    left: -100%;
    right: 0;
    bottom: 0;
    background: 
        radial-gradient(
            circle,
            white,
            transparent 25%
        ) center / 25% 25%,
        radial-gradient(
            circle,
            white,
            black 25%
        ) center / 12.5% 12.5%;
    animation: light 5s linear infinite;
    mix-blend-mode: color-dodge;
}

@keyframes light {
    to {
        transform: translate(50%, 50%);
    }
}

	</style>
</head>
<body>
<audio autoplay="true" style='position:z-index:1;display:none;'  src='https://chencaicc.gitee.io/music/xiaotiaowa.mp3' id="audio" width="100px"></audio>


<canvas id="canvas" style="position:absolute;z-index: 12;">Canvas is not supported in your browser.</canvas>

    <marquee scrollamount='20'>
        <div class="neon">
            <span class="text" data-text="2019小年快乐！">2019小年快乐！</span>
            <span class="gradient"></span>
            <span class="spotlight"></span>
        </div>
    </marquee>





<script>
    /*
        思路：
            通过canvas绘制一张张的图片，然后通过定时器播放这些图片。

            1.创建鞭炮类：其包括鞭炮引线，鞭炮燃放点，鞭炮爆炸点，通过两点之间的连线运动，注意极值的判断[原程序使用的是升空路径来判断的，修改为运动点y轴小于爆炸点y轴表示爆炸了]
            2.创建火焰类：比鞭炮类简单，只要考虑线的绘制以及火焰亮度没有则回收即可，注意循环创建多个

    */
    (function(){

                
        /*    window.requestAnimFrame=(function(){
                return window.requestAnimationFrame
                ||window.webkitRequestAnimationFrame
                ||window.mozRequestAnimationFrame
                ||function(callback){
                        window.setTimeout(callback,1000/60)
                    }
            })();
            */

            var canvas=document.getElementById("canvas"),
                ctx=canvas.getContext("2d"),
                cw=window.innerWidth,
                ch=window.innerHeight,
                fireworks=[],
                particles=[],
                hue=120,
                timerTotal=27,
                timerTick=0,
                mx,
                my;

            canvas.width=cw;
            canvas.height=ch;
            
            function random(min,max){return Math.random()*(max-min)+min}
            
            function calculateDistance(p1x,p1y,p2x,p2y){
                var xDistance=p1x-p2x,
                    yDistance=p1y-p2y;
                return Math.sqrt(Math.pow(xDistance,2)+Math.pow(yDistance,2))
            }
            
            function Firework(sx,sy,tx,ty){
                this.x=sx;//屏幕宽度的一半  -----------------------这是底部发射的点
                this.y=sy;//屏幕高度   -----------------------这是底部发射的点
                this.sx=sx;
                this.sy=sy;
                this.tx=tx;//屏幕宽度内随机   --------------在天上爆炸的点
                this.ty=ty;//屏幕高度一半内随机  --------------------在天上爆炸的点
                // this.distanceToTarget=calculateDistance(sx,sy,tx,ty);//   发射点到爆炸点的距离

                // this.distanceTraveled=0;
                this.coordinates=[];//底部发射点坐标点---记录了3次不知道干嘛的
                this.coordinateCount=3;
                while(this.coordinateCount--)
                    {
                        this.coordinates.push([this.x,this.y]);//最后一项是鞭炮的起点坐标
                    }
                this.angle=Math.atan2(ty-sy,tx-sx);//角度
                this.speed=2;//初始速度
                this.acceleration=1.05;//加速度
                this.targetRadius=1;//半径

                this.brightness=random(50,70);
            }
            
            // 绘制了一个有透明度的点，以及看不到的圆
            Firework.prototype.draw=function(){
                ctx.beginPath();
                ctx.moveTo(this.coordinates[this.coordinates.length-1][0],this.coordinates[this.coordinates.length-1][1]);
                ctx.lineTo(this.x,this.y);
                ctx.strokeStyle="hsl("+hue+", 100%, "+this.brightness+"%)";//鞭炮引线的透明度
                ctx.stroke();
                ctx.beginPath();
                ctx.arc(this.tx,this.ty,this.targetRadius,0,Math.PI*2);
                ctx.stroke()
            };
            
            Firework.prototype.update=function(index){
                this.coordinates.pop();
                this.coordinates.unshift([this.x,this.y]);
                if(this.targetRadius<8){
                    this.targetRadius+=0.3
                }else{
                    this.targetRadius=1
                }
                this.speed*=this.acceleration;
                var vx=Math.cos(this.angle)*this.speed,
                vy=Math.sin(this.angle)*this.speed;

                // this.distanceTraveled=calculateDistance(this.sx,this.sy,this.x+vx,this.y+vy);

                // 运动点的y轴如果小于原定爆炸点的y轴则成立
                if(this.y < this.ty){
                // if(this.distanceTraveled>=this.distanceToTarget){//这个计算太复杂了，用坐标判断简单
                    createParticles(this.tx,this.ty);
                    fireworks.splice(index,1)
                }else{
                    this.x+=vx;this.y+=vy
                }
            };
            
            function Particle(x,y){
                this.x=x;this.y=y;
                this.coordinates=[];
                this.coordinateCount=5;
                while(this.coordinateCount--){
                    this.coordinates.push([this.x,this.y])
                }
                this.angle=random(0,Math.PI*2);
                this.speed=random(1,10);
                this.friction=0.95;
                this.gravity=1;
                this.hue=random(hue-20,hue+20);
                this.brightness=random(50,80);
                this.alpha=1;
                this.decay=random(0.015,0.03)
            }
            
            Particle.prototype.draw=function(){
                ctx.beginPath();
                ctx.moveTo(this.coordinates[this.coordinates.length-1][0],this.coordinates[this.coordinates.length-1][1]);
                ctx.lineTo(this.x,this.y);
                ctx.strokeStyle="hsla("+this.hue+", 100%, "+this.brightness+"%, "+this.alpha+")";
                ctx.stroke()
            };
            
            Particle.prototype.update=function(index){
                this.coordinates.pop();
                this.coordinates.unshift([this.x,this.y]);
                this.speed*=this.friction;
                this.x+=Math.cos(this.angle)*this.speed;
                this.y+=Math.sin(this.angle)*this.speed+this.gravity;
                this.alpha-=this.decay;
                // 结束烟花
                if(this.alpha<=this.decay){
                    particles.splice(index,1)
                }
            };
            
            function createParticles(x,y){
                var particleCount = parseInt(random(200,800));
                // var particleCount=30;
                while(particleCount--){
                    particles.push(new Particle(x,y))
                }
            }
            
            function loop(){

                // 添加定时器
                // requestAnimFrame(loop);
                window.requestAnimationFrame(loop)
                ||window.webkitRequestAnimationFrame(loop)
                ||window.mozRequestAnimationFrame(loop)
                ||window.setTimeout(loop,1000/60)

                hue+=0.5;
                ctx.globalCompositeOperation="destination-out";
                ctx.fillStyle="rgba(0, 0, 0, 0.5)";
                ctx.fillRect(0,0,cw,ch);
                ctx.globalCompositeOperation="lighter";

                // 点火一个爆竹
                if(timerTick>=timerTotal){
                    fireworks.push(new Firework(cw/2+100,ch,random(0,cw),random(100,ch/2)));
                    timerTick=0
                }
                else{ timerTick++}
                
                // 鞭炮升天效果
                var i=fireworks.length;
                while(i--){
                    fireworks[i].draw();
                    fireworks[i].update(i)
                }

                // 烟花粒子[炸开]效果
                var i=particles.length;
                while(i--){
                    particles[i].draw();
                    particles[i].update(i)
                }
            }

            canvas.addEventListener("click",function(e){

                // 有的浏览器要用户操作后才能播放音乐
                if(audio.play){
                    audio.play();
                }

                mx=e.clientX;
                my=e.clientY;
                // console.log(mx,my);
                // 发射点，爆炸点
                fireworks.push(new Firework(cw/2,ch,mx,my));
            });

            var audio=null;

            window.onload=function(){
                audio=document.getElementById('audio')
                // 烟花
                 loop();

                 var play_audio = setInterval(function(){

                    if(audio.play){
                        try{
                        audio.play();

                        }catch(e){}
                    }

                    if(!audio.play){
                        clearInterval(play_audio)
                    }

                 },1000);



            };

    })()



</script>
</body>

</html>